/**
*		@file StmtTable.h
*		@brief StmtTable class
*
*		@author Zhou Nan
*
*		@date 1/25/2012
*/
#ifndef STMTTALBE_H
#define STMTTALBE_H

#include "TNode.h"
#include "GNode.h"
#include "BlkNode.h"
#include "Utility.h"
#include "ProcTable.h"
#include <vector>
#include <sstream>
using namespace std;

typedef vector<bool> StmtSet;
typedef vector<bool> AssignSet;

/**
*		@brief Structure to store data entry
*/
struct StmtEntry{
	// statement index, start from 1
	StmtNum		stmt_num;
	// TNode reference
	TNode*		p_tnode;
	// GNode reference
	GNode*      p_gnode;
	// BlkNode reference
	BlkNode*	p_blknode;
	// procedure that this statement belongs to
	ProcIdx		proc_idx;
};

class StmtTable{
public:
	/**
	*		@brief This method will return the number of StmtEntries in StmtTable
	*/
	static int	GetSize() {return vp_stmt_entries_.size();};

	/**
	*		@brief This method will return the number of Assignment
	*/
	static int	GetSizeAssign() {return assign_stmt_num_.size();};

	/**
	*		@brief This method will return the number of While statement
	*/
	static int	GetSizeWhile() {return while_stmt_num_.size();};

	/**
	*		@brief This method will return the number of If statement
	*/
	static int	GetSizeIf() {return if_stmt_num_.size();};

	/**
	*		@brief This method will return the number of Call statement
	*/
	static int	GetSizeCall() {return call_stmt_num_.size();};

	/**
	*		@brief This method will add a new StmtEntry for stmt_num and p_tnode
	*/
	static void			AddStmtEntry(StmtNum stmt_num, TNode* p_tnode);

	/**
	*		@brief This method will set GNode reference for stmt_num
	*/
	static void			SetStmtGNode(StmtNum stmt_num, GNode* p_gnode);

	/**
	*		@brief This method will set BlkNode reference for stmt_num
	*/
	static void			SetStmtBlkNode(StmtNum stmt_num, BlkNode* p_blknode);

	/**
	*		@brief This method will return TNode reference with stmt_num
	*/
	static TNode*		GetStmtTNode(StmtNum stmt_num);

	/**
	*		@brief This method will return GNode reference with stmt_num
	*/
	static GNode*		GetStmtGNode(StmtNum stmt_num);

	/**
	*		@brief This method will return BlkNode reference with stmt_num
	*/
	static BlkNode*		GetStmtBlkNode(StmtNum stmt_num);

	/**
	*		@brief This method will return TNode reference with assign_num
	*/
	static TNode*		GetAssignTNode(AssignNum assign_num);

	/**
	*		@brief This method will return GNode reference with assign_num
	*/
	static GNode*		GetAssignGNode(AssignNum assign_num);

	/**
	*		@brief This method will return TNode reference with while_num
	*/
	static TNode*		GetWhileTNode(WhileNum while_num);

	/**
	*		@brief This method will return GNode reference with while_num
	*/
	static GNode*		GetWhileGNode(WhileNum while_num);

	/**
	*		@brief This method will return TNode reference with call_num
	*/
	static TNode*		GetCallTNode(CallNum call_num);

	/**
	*		@brief This method will return GNode reference with call_num
	*/
	static GNode*		GetCallGNode(CallNum call_num);

	/**
	*		@brief This method will return TNode reference with if_num
	*/
	static TNode*		GetIfTNode(IfNum if_num);

	/**
	*		@brief This method will return GNode reference with if_num
	*/
	static GNode*		GetIfGNode(IfNum if_num);

	static void			SetProcIdx(StmtNum stmt_num, ProcIdx proc_idx);
	static ProcIdx		GetProcIdx(StmtNum stmt_num);

	/**
	*		@brief This method will return a string representation of StmtTable
	*/
	static string		ToString();

private:
	static vector<StmtEntry*>	vp_stmt_entries_;
	static vector<StmtNum>      assign_stmt_num_;
	static vector<StmtNum>		call_stmt_num_;
	static vector<StmtNum>		if_stmt_num_;
	static vector<StmtNum>		while_stmt_num_;
};

#endif